--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--[[

    武器栏装备【幽幽太行君】，（跑步状态下），右键发动安神秘法：
    消耗当前全部体力（消耗量记为P），基础威力为98a+0.49P
    *开启【蝶隐之时】后，检查是否处于【彼岸蝶舞】形态（也就是刚才的C键技能），如果是，则强制结束【彼岸蝶舞】形态（无需代价，也不会触发【蝶隐之时】），基础威力额外提升0.49H
    *开启【神游界外】后，检查是否处于【通窍】形态（吃了幽幽大行军，会原地复活的形态），如果是，则立刻结束【通窍】形态，本次伤害最终结算时变为1.4倍
    命中的目标如果身上有血梅香效果，则对该目标造成的伤害结算时变为1.4倍，同样会触发一次血梅香伤害同时刷新持续时间。
    发动时，消耗掉当前武器栏里的【幽幽太行君】（这个动作不会产生【幽幽大行军】），记此物品的剩余使用次数为X，胡桃消耗49X点理智，而后挥动炽热的魂灵攻击附近大范围内所有目标，对附近每个目标（包括随从但不包括其他玩家）造成77点物理伤害，并造成上述乘算数值的位面伤害Z。
    也即，该技能的最终伤害公式为：
    Z=（98a+0.49P+0.49H）*b*c*X*火伤系数*攻击系数
    其中a为体力系数a，P为本次消耗体力
    H为开启【彼岸蝶舞】消耗的血量（若未开启则为0）
    b根据是/否处于通窍状态取值为（1.4/1）
    c根据目标是/否处于血梅香状态取值为（1.4/1）
    X为手中的【幽幽太行君】的剩余使用次数

    最终，为胡桃回复【安神秘法】造成总伤害7%的血量。
    *开启【血之灶火】后，血量低于50%时，生命回复量变为造成伤害的21%，血量低于25%时，生命回复量变成造成伤害的28%。
    理智不足49X则无法发动

]]--
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---
    local PHYSICAL_POWER_COST = TUNING.HUTAO_DEBUGGING_MODE and 5 or 21
    local AOE_SPELL_RADIUS = 10
    local SPELL_SANITY_COST_MULT = TUNING.HUTAO_DEBUGGING_MODE and 1 or 49
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 目标扫描TAGS
    local BOUNCE_MUST_TAGS = { "_combat" }
    local BOUNCE_NO_TAGS = { "INLIMBO", "wall", "notarget", "player", "companion", "flight", "invisible", "noattack", "hiding" } -- "player", "companion", "flight", "invisible", "noattack", "hiding"
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 消耗
    local function sanity_dodelta(inst,value,...)
        if inst.components.hutao_com_healing_grove then
            inst.components.hutao_com_healing_grove:SanityDoDelta(value,...)
        else
            inst.components.sanity:DoDelta(value,...)
        end
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 武器检查
    local function WeaponInHandChecker(inst)
        --- X为手中的【幽幽太行君】的剩余使用次数. 理智不足49X则无法发动
        local weapon = inst.replica.combat:GetWeapon() or inst.replica.inventory:GetEquippedItem(EQUIPSLOTS.HANDS)
        if weapon == nil then
            return false
        end
        if weapon.prefab ~= "hutao_equipment_ghostly_march" then
            return false
        end
        if weapon.replica.hutao_com_finiteuses == nil then
            return false
        end
        local current_uses = weapon.replica.hutao_com_finiteuses:GetCurrent()
        local current_sanity = inst.replica.sanity:GetCurrent()
        local mult = SPELL_SANITY_COST_MULT
        if current_sanity < current_uses * mult then
            return false
        end
        return true,weapon
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 技能test
    local function Spell_Test_Fn(inst)
        -- if inst.replica.hutao_com_physical_power:GetCurrent() < PHYSICAL_POWER_COST then
        --     return false
        -- end
        local weapon_flag,weapon = WeaponInHandChecker(inst)
        if not weapon_flag then
            return false
        end
        return true
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---
    local function replica_init(inst,replica)
        replica:SetTestFn(Spell_Test_Fn)
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 虚拟武器创建
    local function GetVisualWeapon(player,base_damage,planar_damage)
        if player.__seal_of_mystery_spell_weapon == nil or not player.__seal_of_mystery_spell_weapon:IsValid() then
            local inst = CreateEntity()
            inst.entity:AddTransform()
            inst:AddTag("weapon")
            inst:AddTag("nosteal")
            inst:AddComponent("weapon")
            inst.components.weapon:SetDamage(7)
            inst.components.weapon:SetRange(100)
            inst:AddComponent("inventoryitem")
            inst.persists = false
            inst.components.inventoryitem:SetOnDroppedFn(inst.Remove)
            inst:AddComponent("equippable")
            inst:AddComponent("planardamage")
            inst.components.planardamage:SetBaseDamage(planar_damage)
            player.__seal_of_mystery_spell_weapon = inst
            inst:DoTaskInTime(10,inst.Remove)
        end

        local weapon = player.__seal_of_mystery_spell_weapon
        weapon.components.weapon:SetDamage(base_damage)
        weapon.components.planardamage:SetBaseDamage(planar_damage)

        return player.__seal_of_mystery_spell_weapon
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- AOE技能 伤害 和 消耗
    --- 获取位面伤害
    local function get_planar_damage(inst,target,weapon)
        --[[
            也即，该技能的最终伤害公式为：
            Z=（98a+0.49P+0.49H）*b*c*X*火伤系数*攻击系数
            其中a为体力系数a，P为本次消耗体力
            H为开启【彼岸蝶舞】消耗的血量（若未开启则为0）
            b根据是/否处于通窍状态取值为（1.4/1）
            c根据目标是/否处于血梅香状态取值为（1.4/1）
            X为手中的【幽幽太行君】的剩余使用次数
        ]]
        local a = inst.components.hutao_com_physical_power:GetModulus()
        local P = inst.components.hutao_com_physical_power:GetCurrent()
        local H = inst.components.hutao_com_butterfly_s_embrace:GetHealthCost()
        local b = 1
        if inst:HasDebuff("hutao_debuff_ghostly_march") then
            b = 1.4
        end
        local c = 1
        if inst.components.hutao_com_blood_plum_scent_for_player:HasDebuff(target) then
            c = 1.4
        end
        local X = 0        
        if weapon and weapon.components.finiteuses then
            X = weapon.components.finiteuses:GetUses()
        end
        --- 火伤系数
        local fire_damage_coefficient = inst.components.hutao_com_fire_damage:GetAdditiveMultipliers()
        --- 攻击系数
        local attack_coefficient = inst.components.combat.externaldamagemultipliers:Get()

        return (98*a+0.49*P+0.49*H)*b*c*X*fire_damage_coefficient*attack_coefficient
    end
    ---- 技能消耗
    local function value_cost(inst,weapon)
        local X = 0        
        if weapon and weapon.components.finiteuses then
            X = weapon.components.finiteuses:GetUses()
        end
        local mult = -SPELL_SANITY_COST_MULT
        -- inst.components.sanity:DoDelta(mult*X,true)
        sanity_dodelta(inst,mult*X,true)
        --- 全部体力消耗
        inst.components.hutao_com_physical_power:SetCurrent(0)
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- AOE技能创建。
    ---- 对单个目标造成伤害。使用虚拟武器。
    local function do_damage_for_single_target(inst,target,weapon)
        local planar_damage = get_planar_damage(inst,target,weapon)
        local visual_weapon = GetVisualWeapon(inst,77,planar_damage)
        -- print("安神秘法",target,planar_damage)
        target.components.combat:GetAttacked(inst, 7, visual_weapon, nil, {
            ["planar"] = planar_damage
        })
    end

    local function spell_aoe_fn(inst,pt)
        local weapon_flag,weapon = WeaponInHandChecker(inst)
        if not weapon_flag or weapon.SetLoopDropBlock == nil then
            return
        end
        ----------------------------------------------
        --- 
            inst:PushEvent("hutao_event.spell_finish_for_plum_blossom",{
                pt = pt,
                radius = AOE_SPELL_RADIUS,
                spell = "seal_of_mystery",
            })
        ----------------------------------------------
        --- 寻找范围内可攻击的目标
            local ents = TheSim:FindEntities(pt.x,0, pt.z,AOE_SPELL_RADIUS, BOUNCE_MUST_TAGS , BOUNCE_NO_TAGS)
            local targets = {}
            local targets_health_before = {} --- 记录每个怪的初始血量
            local targets_health_after = {} --- 记录每个怪被攻击后的血量
            for k, temp_target in pairs(ents) do
                if temp_target and temp_target:IsValid() and temp_target.components.health and not temp_target.components.health:IsDead() then
                    table.insert(targets,temp_target)
                    targets_health_before[temp_target] = temp_target.components.health.currenthealth
                end
            end
        ----------------------------------------------
        --- 造成伤害
            weapon:SetLoopDropBlock(true)
            for k, temp_target in pairs(targets) do
                do_damage_for_single_target(inst,temp_target,weapon)
                targets_health_after[temp_target] = temp_target.components.health.currenthealth
            end
            weapon:SetLoopDropBlock(false)
        ----------------------------------------------
        --- 消耗
            value_cost(inst,weapon)
        ----------------------------------------------
        --- 伤害统计,并回血
            local total_damage = 0
            for k, temp_target in pairs(targets) do
                local damage = (targets_health_before[temp_target] or 0) - (targets_health_after[temp_target] or 0)
                total_damage = total_damage + math.abs(damage)
            end
            local heal_mult = 7/100
            --[[
                *开启【血之灶火】后，血量低于50%时，生命回复量变为造成伤害的21%，
                血量低于25%时，生命回复量变成造成伤害的28%。
            ]]
            if inst.components.hutao_com_talent_tree:IsUnlocked("blood_hearth_fire") then
                local percent = inst.components.health:GetPercent()
                if percent <= 0.25 then
                    heal_mult = 28/100
                elseif percent <= 0.5 then
                    heal_mult = 21/100
                end
            end
            inst.components.health:DoDelta(total_damage*heal_mult)
        ----------------------------------------------
    end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

return function(inst)
    inst:ListenForEvent("HUTAO_OnEntityReplicated.hutao_com_seal_of_mystery",replica_init)
    if not TheWorld.ismastersim then
        return
    end
    inst:AddComponent("hutao_com_seal_of_mystery")
    inst.components.hutao_com_seal_of_mystery:SetAoeFn(spell_aoe_fn)
end